package xml;

import java.util.ArrayList;
import java.util.List;

import lib.SheetInLib;
import main.ErrorException;

import org.jdom.Attribute;
import org.jdom.Element;

import define.Common;
import define.Config;

public class XmlNode
{
	private Element m_node;
	private ArrayList<XmlNode> m_children;
	private int m_rowNumber;
	private int m_columnNumber;
	private int m_x;
	private int m_y;
	private int m_deepth;
	private XmlNode m_father;
	
	public XmlNode(String name)
	{
		m_node = new Element(name);
	}
	
	protected XmlNode(Element node, int deepth, XmlNode father)
	{
		m_node = node;
		m_deepth = deepth;
		m_father = father;
	}
	
	public void addChild(XmlNode node)
	{
		if(m_children == null)
		{
			m_children = new ArrayList<>();
		}
		m_children.add(node);
		m_node.addContent(node.m_node);
	}
	
	public void setText(String text)
	{
		m_node.setText(text);
	}
	
	public void addAttribute(String name, String value)
	{
		m_node.setAttribute(name, value);
	}
	
	protected Element getElement()
	{
		return m_node;
	}
	
	protected int countRow()
	{
		m_rowNumber = 0;
		if(m_children != null)
		{
			for(XmlNode temp: m_children)
			{
				m_rowNumber += temp.countRow();
			}
		}
		if(m_rowNumber == 0)
		{
			m_rowNumber = 1;
		}
		if(hasAttribute())
		{
			m_rowNumber += Config.HAS_ATTRIBUTE_ROW;
		}
		return m_rowNumber;
	}
	
	protected void countColumn()
	{
		m_columnNumber = m_node.getAttributes().size();
		if(hasValue())
		{
			++m_columnNumber;
		}
		if(m_columnNumber == 0)
		{
			m_columnNumber = 1;
		}
		if(m_children != null)
		{
			for(XmlNode temp: m_children)
			{
				temp.countColumn();
			}
		}
	}
	
	public int getRowNumber()
	{
		return m_rowNumber;
	}
	
	public int getColumnNumber()
	{
		return m_columnNumber;
	}
	
	protected void setPosition(int x, int y)
	{
		m_x = x;
		m_y = y;
	}
	
	public int getX()
	{
		return m_x;
	}
	
	public int getY()
	{
		return m_y;
	}
	
	protected void setColumnNumber(int number)
	{
		m_columnNumber = number;
	}
	
	public boolean hasAttribute()
	{
		return m_node.getAttributes().size() > 0 || hasValue();
	}
	
	public boolean hasValue()
	{
		String text = m_node.getText();
		boolean isBlank = true;
		if(text.length() > 0)
		{
			for(int i = 0, max = text.length(); i < max; ++i)
			{
				if(!Common.isBlank(text.charAt(i)))
				{
					isBlank = false;
					break;
				}
			}
		}
		return !isBlank;
	}
	
	public XmlNode getFather()
	{
		return m_father;
	}
	
	protected void makeChildren()
	{
		if(m_node.getChildren().size() > 0)
		{
			m_children = new ArrayList<>();
			int deepth = m_deepth + 1;
			if(XmlDoc.m_deepthList.size() <= deepth)
			{
				XmlDoc.m_deepthList.add(new ArrayList<XmlNode>());
			}
			ArrayList<XmlNode> list = XmlDoc.m_deepthList.get(deepth);
			for(Object temp: m_node.getChildren())
			{
				XmlNode node = new XmlNode((Element)temp, deepth, this);
				list.add(node);
				m_children.add(node);
				node.makeChildren();
			}
		}
	}
	
	protected void toExcel(SheetInLib sheet, int position) throws ErrorException
	{
		sheet.setXmlValue(m_x, m_y, m_node.getName(), position);
		sheet.setColor(m_x, m_y, Config.NODE_COLOR, position);
		if(hasAttribute())
		{
			int height = m_rowNumber - Config.HAS_ATTRIBUTE_ROW;
			sheet.setMerge(m_x, m_y, m_columnNumber, height);	
			@SuppressWarnings("rawtypes")
			List list = m_node.getAttributes();
			int i = 0;
			for(int max = list.size(); i < max; ++i)
			{
				Attribute attr = (Attribute)list.get(i);
				sheet.setXmlValue(m_x + i, m_y + height, attr.getName(), position);
				sheet.setXmlValue(m_x + i, m_y + height + 1, attr.getValue(), position);
			}
			if(hasValue())
			{
				sheet.setXmlValue(m_x + i, m_y + height, "", position);
				sheet.setXmlValue(m_x + i, m_y + height + 1, m_node.getText(), position);
				++i;
			}
//			if(i < m_rowNumber)
//			{
//				sheet.setMerge(m_x + 1, m_y + i - 1, 1, m_rowNumber - i + 1);
//				sheet.setMerge(m_x + 2, m_y + i - 1, 1, m_rowNumber - i + 1);
//			}
			sheet.setColor(m_x, m_y + height, Config.ATTRIBUTE_DEFAULT_COLOR, position);
		}
		else
		{
			sheet.setMerge(m_x, m_y, m_columnNumber, m_rowNumber);
		}
	}
}
